using System;
using System.Collections.Generic;
using System.Reflection;

namespace UnityEngine.Recorder
{
	public static class RecordersInventory
	{
		internal static SortedDictionary<string, RecorderInfo> m_Recorders
		{
			get;
			private set;
		}

		private static IEnumerable<KeyValuePair<Type, object[]>> FindRecorders()
		{
			Type attribType = typeof(RecorderAttribute);
			Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
			foreach (Assembly a in assemblies)
			{
				Type[] types;
				try
				{
					types = a.GetTypes();
				}
				catch (Exception)
				{
					UnityEngine.Debug.LogError("Failed reflecting assembly: " + a.FullName);
					continue;
				}
				Type[] array = types;
				foreach (Type t in array)
				{
					object[] attributes = t.GetCustomAttributes(attribType, inherit: false);
					if (attributes.Length != 0)
					{
						yield return new KeyValuePair<Type, object[]>(t, attributes);
					}
				}
			}
		}

		private static void Init()
		{
		}

		private static bool AddRecorder(Type recorderType)
		{
			object[] customAttributes = recorderType.GetCustomAttributes(typeof(RecorderAttribute), inherit: false);
			if (customAttributes.Length == 1)
			{
				RecorderAttribute recorderAttribute = customAttributes[0] as RecorderAttribute;
				if (m_Recorders == null)
				{
					m_Recorders = new SortedDictionary<string, RecorderInfo>();
				}
				RecorderInfo recorderInfo = new RecorderInfo();
				recorderInfo.recorderType = recorderType;
				recorderInfo.settingsClass = recorderAttribute.settings;
				recorderInfo.category = recorderAttribute.category;
				recorderInfo.displayName = recorderAttribute.displayName;
				RecorderInfo recorderInfo2 = recorderInfo;
				m_Recorders.Add(recorderInfo2.recorderType.FullName, recorderInfo2);
				return true;
			}
			UnityEngine.Debug.LogError($"The class '{recorderType.FullName}' does not have a FrameRecorderAttribute attached to it. ");
			return false;
		}

		public static RecorderInfo GetRecorderInfo<TRecorder>() where TRecorder : class
		{
			return GetRecorderInfo(typeof(TRecorder));
		}

		public static RecorderInfo GetRecorderInfo(Type recorderType)
		{
			Init();
			if (m_Recorders.ContainsKey(recorderType.FullName))
			{
				return m_Recorders[recorderType.FullName];
			}
			if (AddRecorder(recorderType))
			{
				return m_Recorders[recorderType.FullName];
			}
			return null;
		}

		public static IEnumerable<RecorderInfo> ListRecorders()
		{
			Init();
			foreach (KeyValuePair<string, RecorderInfo> recorder in m_Recorders)
			{
				yield return recorder.Value;
			}
		}

		public static Recorder GenerateNewRecorder(Type recorderType, RecorderSettings settings)
		{
			Init();
			RecorderInfo recorderInfo = GetRecorderInfo(recorderType);
			if (recorderInfo != null)
			{
				Recorder recorder = ScriptableObject.CreateInstance(recorderType) as Recorder;
				recorder.Reset();
				recorder.settings = settings;
				return recorder;
			}
			throw new ArgumentException("No factory was registered for " + recorderType.Name);
		}
	}
}
